@jargon/sdk-core
Jargon's SDK core package contains functionality common to multiple voice platforms and
frameworks.
Core concepts
Content resources and resource files
Content resources define the text that may vary across user locales.
Resource files are JSON, with a single top-level object (similar to package.json). The keys within that
object are the identifiers you'll use to refer to specific resources within your source code. Nested objects
are supported to help you organize your resources.
{
"key1":"Text for key 1",
"key2":"Text for key 2",
"nestedObjects":{
"are":{
"supported":"Use the key 'nestedObjects.are.supported' to refer to this resource"
}
}
}
Resource value format
Resource values are in ICU MessageFormat. This
format supports constructing text at runtime based on parameters passed in from your code, and selecting
alternative forms to handle things like pluralization and gender.
Named parameters
{
"sayHello":"Hello {name}"
}
Plural forms
{
"itemCount":"{count, plural, =0 {You have zero items} =1 {You have one item} other {You have # items}}"
}
Gendered forms
{
"pronounSelection":"{gender, select, female {She did it!} male {He did it!} other {It did it!}"
}
Variations
Resources can have multiple variations. Variations are defined using nested objects:
{
"resourceWithVariations":{
"v1":"First variation",
"v2":"Second variation",
"v3":"Third variation"
}
}
When rendering the key resourceWithVariations
the ResourceManager
will choose a variation at random (with other more complex
methods coming in future versions). If you render the same resource multiple times within a single request (e.g., for spoken
content and for card or screen content) the ResourceManager
will by default consistently choose the same variation.
Note that you can always select a specific variation using its fully-qualified key (e.g., resourceWithVariations.v1
)
You can determine which variation the was choses via the ResourceManager's selectedVariation(s) routines.
Functionality
Resource management and runtime rendering
ResourceManager
allows clients to access content resources stored in locale-specific
files, and to render those resources at runtime, substituting parameters.
A ResourceManager
instance is meant to live only for the lifetime of a single request, and is bound
to a specific locale. Instances are created via a ResourceManagerFactory
instance, normally DefaultResourceManagerFactory
.
Resource files live in "resources" subdirectory of the process's runtime directory; this will soon be customizable via
ResourceManagerOptions
.
Built-in Resources
This SDK includes default responses for some common scenarios. These responses are available using the following RenderItem
keys:
Jargon.unhandledResponse
-- provides a response for when you can't otherwise process an intentJargon.defaultReprompt
-- provides a generic reprompt
You can render these resources as you would any of your own, as described in the following section. You can also define your own version for these keys in your resource file to override the Jargon-provided responses.
Currently the SDK includes variants of these resources for English, with other languages coming soon.
Runtime Interface
RenderItem
A RenderItem specifies a resource key, optional parameters, and options to control details of the rendering (which
are themselves optional).
interface RenderItem {
key: string
params?: RenderParams
options?: RenderOptions
}
RenderParams
are a map from parameter name to a string, number, or RenderItem
instance.
interface RenderParams {
[param: string]: string | number | RenderItem
}
The use of a RenderItem
instance as a parameter value makes it easy to compose multiple
resource together at runtime. This is useful when a parameter value varies across locales,
or when you want the SDK to select across multiple variations for a parameter value, and reduces
the need to chain together multiple calls into the ResourceManager
.
The ri
helper function simplifies constructing a RenderItem
:
function ri (key: string, params?: RenderParams, options?: RenderOptions): RenderItem
rm.render(ri('sayHello', { 'name': 'World' }))
RenderOptions
allows fine-grained control of rendering behavior for a specific call, overriding
the configuration set at the ResourceManager
level.
interface RenderOptions {
readonly forceNewRandom?: boolean
}
ResourceManager
ResourceManager
is the core interface for rendering locale-specific content at runtime.
export interface ResourceManager {
render (item: RenderItem): Promise<string>
renderBatch (items: RenderItem[]): Promise<string[]>
renderObject<T> (item: RenderItem): Promise<T>
selectVariationFromObject (item: RenderItem, obj: any): Promise<string>
selectedVariation (item: RenderItem): Promise<SelectedVariation>
selectedVariations (): Promise<SelectedVariation[]>
readonly locale: string
}
Note that the render routines return Promise
s to the rendered content, not the content directly.
ResourceManagerFactory
A ResourceManagerFactory
construct locale-specific ResourceManager
instance.
export interface ResourceManagerFactory {
forLocale (locale: string): ResourceManager
}
Locales name use the standard BCP-47 tags, such as 'en-US' or 'de-DE'.
ResourceManagerOptions
Options for controlling resource manager functionality. Defaults are specified in DefaultResourceManagerOptions
.
export interface ResourceManagerOptions {
consistentRandom?: boolean
localesToPreload?: string[]
trackSelectedVariations?: boolean
resourceDirectory?: string
}
export const DefaultResourceManagerOptions: Required<ResourceManagerOptions> = {
consistentRandom: true,
localesToPreload: [],
trackSelectedVariations: true,
resourceDirectory: './resources'
}
RenderOptions
Options for controlling rendering behavior, overriding the ResourceManager
s configuration.
Defaults are specified in DefaultRenderOptions
.
export interface RenderOptions {
readonly forceNewRandom?: boolean
}
export const DefaultRenderOptions: RenderOptions = {
forceNewRandom: false
}
Usage
const sdkCore = require('@jargon/sdk-core');
const options = {}
const resourceManagerFactory = new sdkCore.DefaultResourceManagerFactory(options)
const resourceManager = resourceManagerFactory.forLocale('en-US')
const contentPromise = resourceManager.render(sdkCore.ri('sayHello', { 'name': 'World' }))